#include "slepbase.h"

void LogisticR(slep_matrix* A, slep_vector* y, double z, OPTS* opts,
				 slep_vector* x, double *c, slep_vector* funVal, slep_vector* valueL);
void nnLogisticR(slep_matrix* A, slep_vector* y, double z, OPTS* opts,
				 slep_vector* x, double *c, slep_vector* funVal);

int LeastR(slep_matrix* A, slep_vector* y, double z, OPTS *opts, 
			slep_vector* x, slep_vector* funVal, slep_vector* valueL);


void exampleLogisticR(){
	int i;
	OPTS opts;
	slep_vector* x, *funVal, *valueL, *y;
	slep_matrix* A;
	double c;
	A = slepAllocDenseMatrix(1000,1000);
	y = slepAllocDenseVector(1000);
	x = slepAllocDenseVector(1000);
	funVal = slepAllocDenseVector(1000);
	valueL = slepAllocDenseVector(1000);
	DMEMSET(y->data.vctr,1.0,500,i);
	DMEMSET(&(y->data.vctr[500]),-1.0,500,i);
	slep_randn(A->data.mtrx,1000*1000, 0.0,1.0);
	opts.nFlag = 0;
	opts.rFlag = 1;
	opts.sWeight[0]=opts.sWeight[1]=1;
	opts.init = 2;
	opts.tFlag = 5;
	opts.maxIter = 100;
	opts.REGISTER = 0;
	opts.REGISTER = SlepOPT_maxIter | SlepOPT_sWeight ;

	opts.lFlag = 0;
	opts.mFlag = 0;
	LogisticR(A,y,0.1,&opts,x,&c,funVal,valueL);
	slepWriteDenseMatrix("A.slm",A);
	slepWriteDenseVector("y.slv",y);
	slepWriteDenseVector("x1-LogR.slv",x);
	slepWriteDenseVector("funVal1-LogR.slv",funVal);
	slepWriteDenseVector("LVal1-LogR.slv",valueL);

	opts.mFlag = 1;
	opts.lFlag = 0;
	opts.tFlag = 2;
	opts.tol = funVal->data.vctr[99];
	opts.maxIter = 1000;
	opts.REGISTER = SlepOPT_maxIter | SlepOPT_sWeight | SlepOPT_tol ;
	LogisticR(A,y,0.1,&opts,x,&c,funVal,valueL);
	slepWriteDenseVector("x2-LogR.slv",x);
	slepWriteDenseVector("funVal2-LogR.slv",funVal);
	slepWriteDenseVector("LVal2-LogR.slv",valueL);

	opts.mFlag = 1;
	opts.lFlag = 1;
	LogisticR(A,y,0.1,&opts,x,&c,funVal,valueL);
	slepWriteDenseVector("x3-LogR.slv",x);
	slepWriteDenseVector("funVal3-LogR.slv",funVal);
	slepWriteDenseVector("LVal3-LogR.slv",valueL);

}




void exampleNNLogisticR(){
	int i;
	OPTS opts;
	slep_vector* x, *funVal, *y;
	slep_matrix* A;
	double c;
	A = slepAllocDenseMatrix(1000,1000);
	y = slepAllocDenseVector(1000);
	x = slepAllocDenseVector(1000);
	funVal = slepAllocDenseVector(1000);
	DMEMSET(y->data.vctr,1.0,500,i);
	DMEMSET(&(y->data.vctr[500]),-1.0,500,i);
	slep_randn(A->data.mtrx,1000*1000, 0.0,1.0);
	opts.nFlag = 0;
	opts.rFlag = 1;
	opts.sWeight[0]=opts.sWeight[1]=1;
	opts.init = 2;
	opts.tFlag = 5;
	opts.maxIter = 100;
	opts.REGISTER = 0;
	opts.REGISTER = SlepOPT_maxIter | SlepOPT_sWeight ;

	opts.lFlag = 0;
	opts.mFlag = 0;
	nnLogisticR(A,y,0.1,&opts,x,&c,funVal);
	slepWriteDenseMatrix("A.slm",A);
	slepWriteDenseVector("y.slv",y);
	slepWriteDenseVector("x1-nnLogR-C.slv",x);
	slepWriteDenseVector("funVal1-nnLogR-C.slv",funVal);

	opts.mFlag = 1;
	opts.lFlag = 0;
	opts.tFlag = 2;
	opts.tol = funVal->data.vctr[99];
	opts.maxIter = 1000;
	opts.REGISTER = SlepOPT_maxIter | SlepOPT_sWeight | SlepOPT_tol ;
	nnLogisticR(A,y,0.1,&opts,x,&c,funVal);
	slepWriteDenseVector("x2-nnLogR-C.slv",x);
	slepWriteDenseVector("funVal2-nnLogR-C.slv",funVal);
}


void testRunLeastR1(){
	int i;
	OPTS opts;
	slep_matrix* A;
	slep_vector *x, *y, *funVal, *LValue;
	double rho;
	stopWatch timer;

	A = slepAllocDenseMatrix(1000,1000);
	x = slepAllocDenseVector(1000);
	y = slepAllocDenseVector(1000);
	funVal = slepAllocDenseVector(1000);
	LValue = slepAllocDenseVector(1000);

	slep_randn(A->data.mtrx,1000*1000,0.,1.);
	slep_randn(x->data.vctr,1000,0.,1.); // its xOrin here..
	slep_randn(y->data.vctr,1000,0.,1.);
	slep_daAxpby(SlepNoTranspose,1.,A,x,0.01,y);



	opts.lFlag=0;
	opts.mFlag=0;
	opts.nFlag=0;

	opts.rsL2=0;
	opts.maxIter=100;

	startTimer(&timer);
	memset(x->data.vctr,0,sizeof(double)*1000);
	stopTimer(&timer);
	printf("Time taken for setting zeroes = %lf\n", getElapsedTime(&timer));

	startTimer(&timer);
	slep_dvcopy(x,funVal);
	stopTimer(&timer);
	printf("Time taken for copying = %lf\n", getElapsedTime(&timer));

	startTimer(&timer);
	slep_daxpy(1.,x,funVal);
	stopTimer(&timer);
	printf("Time taken for daxpy = %lf\n", getElapsedTime(&timer));

	startTimer(&timer);
	slep_ddot(x,funVal);
	stopTimer(&timer);
	printf("Time taken for ddot = %lf\n", getElapsedTime(&timer));

	startTimer(&timer);
	slep_dasum(x);
	stopTimer(&timer);
	printf("Time taken for dasum = %lf\n", getElapsedTime(&timer));

	startTimer(&timer);
	slep_dnrm2(x);
	stopTimer(&timer);
	printf("Time taken for dnrm2 = %lf\n", getElapsedTime(&timer));

	slepWriteDenseMatrix("A-LeastR.slm",A);
	slepWriteDenseVector("y-LeastR.slv",y);
	opts.init = 2;
	opts.tFlag=5;
	opts.maxIter = 100;
	opts.REGISTER = SlepOPT_maxIter | SlepOPT_rsL2;
	opts.rsL2 = 0.0;
	opts.rFlag = 1;
	rho=0.2;

	opts.mFlag=0;
	opts.lFlag=0;
	startTimer(&timer);
	LeastR(A,y,rho,&opts,x,funVal,LValue);
	stopTimer(&timer);
	printf("Time taken = %lf\n", getElapsedTime(&timer));

	slepVerboseWriteDenseVector("x-LeastR-1.slv",x);
	slepVerboseWriteDenseVector("f-LeastR-1.slv",funVal);
	slepVerboseWriteDenseVector("L-LeastR-1.slv",LValue);

	opts.mFlag=1;
	opts.lFlag=0;
	startTimer(&timer);
	LeastR(A,y,rho,&opts,x,funVal,LValue);
	stopTimer(&timer);
	printf("Time taken = %lf\n", getElapsedTime(&timer));
	slepVerboseWriteDenseVector("x-LeastR-2.slv",x);
	slepVerboseWriteDenseVector("f-LeastR-2.slv",funVal);
	slepVerboseWriteDenseVector("L-LeastR-2.slv",LValue);

	opts.mFlag=1;
	opts.lFlag=1;
	startTimer(&timer);
	LeastR(A,y,rho,&opts,x,funVal,LValue);
	stopTimer(&timer);
	printf("Time taken = %lf\n", getElapsedTime(&timer));
	slepVerboseWriteDenseVector("x-LeastR-3.slv",x);
	slepVerboseWriteDenseVector("f-LeastR-3.slv",funVal);
	slepVerboseWriteDenseVector("L-LeastR-3.slv",LValue);



}